/**
 * Copyright (C) 2013 DaiKit.com - daikit4gxt module (admin@daikit.com)
 *
 *         Project home : http://code.daikit.com/daikit4gxt
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.daikit.daikit4gxt.client;

import com.allen_sauer.gwt.log.client.Log;
import com.daikit.daikit4gxt.client.resources.DkBaseI18n;
import com.daikit.daikit4gxt.client.resources.DkBaseResources;
import com.daikit.daikit4gxt.client.resources.DkBaseStyle;
import com.daikit.daikit4gxt.client.screen.DkBaseScreen;
import com.daikit.daikit4gxt.client.ui.DkBaseGui;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.sencha.gxt.core.client.resources.StyleInjectorHelper;


/**
 * Main class implementing {@link EntryPoint}. It has to be the GWT entry point of your application.<br>
 * You should extend this class to create your proper entry point for your application.
 *
 * @author tcaselli
 * @version $Revision$ Last modifier: $Author$ Last commit: $Date$
 */
public class DkBaseMain implements EntryPoint
{

	protected static DkBaseResources resources;
	protected static DkBaseI18n i18n;
	protected static DkBaseMainController controller;
	protected static DkBaseApplicationModel model;
	protected static DkBaseErrorHandler errorHandler;
	protected static DkBaseConfiguration configuration;

	/**
	 * Default paging size = 25
	 */
	public static int SCREEN_PAGING_SIZE = 25;
	/**
	 * Default reference selector paging size = 25
	 */
	public static int REFERENCE_SELECTOR_PAGING_SIZE = 25;

	/**
	 * Setup an UncaughtExceptionHandler, which is as easy as calling Log.setUncaughtExceptionHandler() before you do
	 * anything else in your module. Note that you will need to use a DeferredCommand and void any constructor or
	 * stand-alone initialization code in your EntryPoint class if you really want to catch everything in web mode. In
	 * Firefox and IE this will even catch exceptions thrown in setTimeout() or setInterval() functions.
	 */
	@Override
	public void onModuleLoad()
	{
		/*
		 * Install an UncaughtExceptionHandler which will produce <code>FATAL</code> log messages
		 */
		Log.setUncaughtExceptionHandler();

		/*
		 * Use a deferred command so that the UncaughtExceptionHandler catches any exceptions in onModuleLoad2()
		 */
		Scheduler.get().scheduleDeferred(new ScheduledCommand()
		{
			@Override
			public void execute()
			{
				onModuleLoad2();
			}
		});
	}

	/**
	 * Effective module load function.
	 */
	protected final void onModuleLoad2()
	{
		i18n = createI18n();
		resources = createResources();
		StyleInjectorHelper.ensureInjected(style(), true);
		errorHandler = createErrorHandler();
		model = createApplicationModel();
		configuration = createConfiguration();
		final DkBaseGui gui = createGui();
		controller = createMainController(gui);
		controller.invalidateUi(true);
		controller.onApplicationLoaded();
	}

	// *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
	// METHODS TO BE OVERRIDDEN
	// *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

	protected DkBaseErrorHandler createErrorHandler()
	{
		return new DkBaseErrorHandler();
	}

	protected DkBaseApplicationModel createApplicationModel()
	{
		return new DkBaseApplicationModel();
	}

	protected DkBaseGui createGui()
	{
		return new DkBaseGui();
	}

	protected DkBaseConfiguration createConfiguration()
	{
		return new DkBaseConfiguration();
	}

	protected DkBaseMainController createMainController(final DkBaseGui gui)
	{
		return new DkBaseMainController(gui)
		{
			@Override
			protected <S extends DkBaseScreen> DkBaseScreen getSpecificScreenInstance(final Class<S> clazz)
			{
				return null;
			}

			@Override
			public Class<? extends DkBaseScreen> getDefaultScreen()
			{
				return null;
			}
		};
	}

	protected DkBaseResources createResources()
	{
		return GWT.create(DkBaseResources.class);
	}

	protected DkBaseI18n createI18n()
	{
		return GWT.create(DkBaseI18n.class);
	}

	// *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
	// METHODS
	// *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

	// *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
	// GETTERS AND SETTERS
	// *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

	/**
	 * @return the main controller which should extend {@link DkBaseMainController}. You should extend this function to
	 *         type the returned controller.
	 */
	public static DkBaseMainController controller()
	{
		return controller;
	}

	/**
	 * @return the application model which should extend {@link DkBaseMainController}. You should extend this function to
	 *         type the returned model.
	 */
	public static DkBaseApplicationModel model()
	{
		return model;
	}

	/**
	 * @return the {@link DkBaseResources}
	 */
	public static DkBaseResources resources()
	{
		return resources;
	}

	/**
	 * @return the {@link DkBaseResources}
	 */
	public static DkBaseResources icons()
	{
		return resources();
	}

	/**
	 * @return the {@link DkBaseI18n}
	 */
	public static DkBaseI18n i18n()
	{
		return i18n;
	}

	/**
	 * @return the {@link DkBaseStyle} contained in {@link DkBaseResources}
	 */
	public static DkBaseStyle style()
	{
		return resources.baseStyle();
	}

	/**
	 * @return the {@link DkBaseErrorHandler}
	 */
	public static DkBaseErrorHandler errorHandler()
	{
		return errorHandler;
	}

	/**
	 * @return the {@link DkBaseConfiguration}
	 */
	public static DkBaseConfiguration config()
	{
		return configuration;
	}
}
